using System;
using System.Collections;
using System.IO;
using Slaks.DocumentSerialization.Document;
using Slaks.DocumentSerialization.ParsedFiles;

namespace Slaks.Postprocessing
{
	public class SentenceAdjustment
	{
		private string m_parsedFileList;
		private string m_outputPath;
		public SentenceAdjustment(string parsedFileList,string outputPath)
		{
			m_parsedFileList = parsedFileList;
			m_outputPath = outputPath;
			if (m_outputPath[m_outputPath.Length - 1] != '\\') m_outputPath += "\\";
		}

		public void Adjust()
		{
			IList parsedFileList = ParsedFiles.ReadXml(m_parsedFileList);
			foreach(string file in parsedFileList)
			{
				Console.WriteLine(file);
				Document document = this.ParseDocument(file);
				ContinueAdjusting(document);
				this.WriteDocumentBack(document);
			}
		}

		private void ContinueAdjusting(Document document)
		{
			bool isBlankSentenceExists = true;
			do
			{
				this.AdjustDocument(document);
				this.UpdateSentenceCount(document);
				isBlankSentenceExists = this.IsBlankSentenceNumberExists(document);
			}while(isBlankSentenceExists == true);
		}

		private Document ParseDocument(string file)
		{
			Document document = null;
			document = Xml2Document.ReadXml(file);
			return document;
		}

		private void AdjustDocument(Document document)
		{
			for(int i=0;i<document.TotalSentenceCount;i++)
			{
				if (this.IsSentenceNumberExists(document,i)) continue;
				this.ChangeSentenceNumberTo(document,i+1);
			}
		}

		private void UpdateSentenceCount(Document document)
		{
			long sentenceCount = -1;
			foreach(Node node in document.Nodes)
			{
				foreach(Section section in node.Sections)
				{
					foreach(Sentence sentence in section.Sentences)
					{
						if (sentence.Number > sentenceCount)
						{
							sentenceCount = sentence.Number;
							document.TotalSentenceCount = sentenceCount + 1;
						}
					}
				}
			}
		}

		private bool IsBlankSentenceNumberExists(Document document)
		{
			for (int i=0;i < document.TotalSentenceCount; i++)
				if (this.IsSentenceNumberExists(document,i) == false) return true;

			return false;
		}

		private bool IsSentenceNumberExists(Document document,long sentenceNumber)
		{
			foreach(Node node in document.Nodes)
			{
				foreach(Section section in node.Sections)
				{
					foreach(Sentence sentence in section.Sentences)
					{
						if (sentence.Number == sentenceNumber) return true;
					}
				}
			}

			return false;
		}

		private void ChangeSentenceNumberTo(Document document, long changeFrom)
		{
			foreach(Node node in document.Nodes)
			{
				foreach(Section section in node.Sections)
				{
					foreach(Sentence sentence in section.Sentences)
					{
						if (sentence.Number >= changeFrom) sentence.Number = sentence.Number - 1;
					}
				}
			}
		}

		private void WriteDocumentBack(Document document)
		{
			string filename = document.FileName;
			FileInfo info = new FileInfo(filename);
			string nameOnly = info.Name;
			string output = m_outputPath + nameOnly;
			Document2Xml.WriteXml(document,output,System.Text.Encoding.UTF8);
		}
	}
}
